package org.ajc.gift.service.impl;

import org.ajc.gift.clients.AuthClient;
import org.ajc.gift.constants.UserConstants;
import org.ajc.gift.domain.LoginUser;
import org.ajc.gift.domain.User;
import org.ajc.gift.domain.UserInfo;
import org.ajc.gift.domain.loginRegisterDto;
import org.ajc.gift.exception.BusinessException;
import org.ajc.gift.exception.ResponseCode;
import org.ajc.gift.exception.RonghuaAssert;
import org.ajc.gift.mapper.UserInfoMapper;
import org.ajc.gift.mapper.UserMapper;
import org.ajc.gift.service.IUserService;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import org.ajc.gift.util.AjaxResult;
import org.ajc.gift.util.encrypt.MD5;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.UUID;

/**
 * <p>
 * 会员登录账号 服务实现类
 * </p>
 *
 * @author ajc
 * @since 2024-03-22
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private UserInfoMapper userInfoMapper;

    @Autowired
    private AuthClient authClient;


    @Override
    @Transactional
    public AjaxResult register(loginRegisterDto dto) {
        //1.参数校验 jsr303做了,不用在做了
        //校验验证码是否匹配 需要做
        String phone = dto.getPhone();
        String key = UserConstants.USER_REGISTER_SEND_SMS_KEY+"-"+phone; //将以“-”隔开
        String codeByRedis = (String)redisTemplate.opsForValue().get(key); //验证码发送时间
        //如果Redis里面的数据为空,说明数据已经过期了,提示 重新获取
        RonghuaAssert.isNotBlank(codeByRedis, ResponseCode.RESPONSE_CODE_400009);
        //如果不为空,比对密码是否一致
        String code = codeByRedis.split(":")[0]; //分隔获取第一个
        RonghuaAssert.isEq(dto.getVerifyCode(),code,ResponseCode.RESPONSE_CODE_400009);

        //2.密码加盐加密,
        String salt = UUID.randomUUID().toString().replaceAll("-","");
        String password = MD5.getMD5("ajc"+salt+dto.getPassword()+"test");

        //3.保存数据到数据库
        //先保存数据到t_user_login,并且要获取login_id
        LoginUser loginUser = new LoginUser();
        //用户注册时没有用户名,随机生成一个字符串作为用户名
        loginUser.setUsername(UUID.randomUUID().toString());
        loginUser.setSalt(salt);
        loginUser.setPassword(password);
        loginUser.setTel(dto.getPhone());
        loginUser.setType(1);
        AjaxResult ajaxResult = authClient.addOrUpdate(loginUser);
        //远程调用获取授权服务保存信息,有可能会报错不成功,如果报错应该抛出异常,防止程序继续往下执行
        if (!ajaxResult.isSuccess()){
           throw new BusinessException(ajaxResult.getMessage());
        }
        Long loginId = Long.parseLong(ajaxResult.getResultObj().toString());


        //再保存到t_user表中,获取到user_id
        User user = new User();
        user.setCreateTime(new Date().getTime());
        user.setPhone(dto.getPhone());
        user.setPassword(dto.getPassword());
        user.setSalt(null);
        user.setBitState(1L);
        user.setSecLevel(1);
        user.setLoginId(loginId);
        insert(user);

        //4.拿到t_user表中user_id,最后数据保存到t_user_info
        // 最后数据保存到t_user_info
        UserInfo userInfo = new UserInfo();
        userInfo.setRegTime(new Date().getTime());
        userInfo.setLevel(0);
        userInfo.setGrowScore(0);
        userInfo.setUserId(user.getId());
        userInfoMapper.insert(userInfo);

        //5.注册成功消息返回给前端用户,发送短信/发生邮件 -- 消息队列@TODO

        return AjaxResult.me();

    }
}
